package com.hui.web;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hui.processor.CityItemProcessor;
import org.mybatis.spring.batch.MyBatisBatchItemWriter;
import org.mybatis.spring.batch.MyBatisPagingItemReader;
import org.springframework.batch.core.*;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.support.CompositeItemProcessor;
import org.springframework.batch.item.support.CompositeItemWriter;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Created by Hui
 * on 2017/5/18 0018.
 */
@RestController
public class CityJobController extends AbstractLauncher {

    private final CityItemProcessor cityItemProcessor;

    public CityJobController(CompositeItemProcessor compositeItemProcessor, ThreadPoolTaskExecutor taskExecutor, JobLauncher jobLauncher, JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory, MyBatisBatchItemWriter batisBatchItemWriter, MyBatisPagingItemReader itemReader, CityItemProcessor cityItemProcessor) {
        super(compositeItemProcessor, taskExecutor, jobLauncher, jobBuilderFactory, stepBuilderFactory, batisBatchItemWriter, itemReader);
        this.cityItemProcessor = cityItemProcessor;
    }

    public void onLauncher() {
        //Set Reader QueryId
        itemReader.setQueryId("com.hui.mapper.CityMapper.selectCityById");
        //方法需要参数
        Map<String, Object> params = Maps.newHashMap();
        params.put("id", 1);
        itemReader.setParameterValues(params);

        //Set Writer StatementId
        batisBatchItemWriter.setStatementId("org.uugu.core.dao.daysettle.ADao.saveA");

        //Create Parameter for Processor
        Map<String, Object> param = Maps.newHashMap();
        param.put("date", new Date());
        cityItemProcessor.setParameterValues(param);
        //使用符合Writer，实现多Writer，可像多个数据库中写入数据，当然第二个Writer的写入操作要自己代码实现，注意同事务中MyBatis的ExcuteType不可改变
        CompositeItemWriter compositeItemWriter = new CompositeItemWriter();
        List delegates = Lists.newArrayList();
        delegates.add(batisBatchItemWriter);
        compositeItemWriter.setDelegates(delegates);

        //Build Step
        Step step = stepBuilderFactory.get("calculateDaySettleInfoStep1")
                .chunk(1000)  //1000次处理提交一次事务
                .reader(itemReader)
                .processor(cityItemProcessor)
                .writer(compositeItemWriter)
                .taskExecutor(taskExecutor)            //If you need can be used.
                .faultTolerant()                        //容错
                .skipLimit(10)                           //可以异常跳过10次，多了就任务失败
                .skip(NullPointerException.class)        //空指针异常可以跳过，继续执行
//                .listener()
                .build();

        //Build Job
        Job job = jobBuilderFactory.get("calculateDaySettleInfoJob1").incrementer(new RunIdIncrementer()).start(step).build();
        JobParameters parameters = new JobParametersBuilder()
                .addString("runDay", UUID.randomUUID().toString())  //该参数参数相同Job不会执行
                .toJobParameters();
        try {
            //Start Job
            JobExecution result = jobLauncher.run(job, parameters);
            System.out.println("===" + result.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}